/**
 * websocket-device.js
 * 设备状态实时更新 - WebSocket 单例工具
 */
class DeviceWebSocket {
    constructor() {
        this.ws = null;
        this.url = this.getWebSocketUrl();
        this.messageListeners = []; // 所有订阅消息的回调
        this.readyState = 'CLOSED'; // CLOSED, CONNECTING, OPEN
        this.reconnectDelay = 3000; // 重连间隔 ms
        this.maxReconnectDelay = 30 * 1000; // 最大重连时间 30s
        this.reconnectTimer = null;

        // 动态获取当前服务地址（兼容不同环境）
        this.connect();
    }

    getWebSocketUrl() {
        // 如果页面未提供，默认值
        const defaultHost = window.location.hostname;
        const defaultPort = window.location.port;
        return `ws://${defaultHost}:${defaultPort}/ws/device-status`;
    }

    connect() {
        if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
            console.warn("WebSocket already connecting or connected.");
            return;
        }

        this.readyState = 'CONNECTING';
        console.log(`🔌 正在连接 WebSocket: ${this.url}`);

        this.ws = new WebSocket(this.url);

        this.ws.onopen = () => {
            console.log("✅ WebSocket 已连接");
            this.readyState = 'OPEN';
            this.clearReconnectTimer();
        };

        this.ws.onmessage = (event) => {
            try {
                const data = JSON.parse(event.data);
                this.dispatchMessage(data);
            } catch (e) {
                console.warn("Received non-JSON message:", event.data);
                this.dispatchMessage(event.data); // 原始字符串也派发
            }
        };

        this.ws.onclose = () => {
            console.log("❌ WebSocket 已断开，准备重连...");
            this.readyState = 'CLOSED';
            this.scheduleReconnect();
        };

        this.ws.onerror = (err) => {
            console.error("WebSocket 错误:", err);
        };
    }

    /**
     * 广播消息给所有监听器
     */
    dispatchMessage(data) {
        this.messageListeners.forEach(cb => {
            try {
                cb(data);
            } catch (e) {
                console.error("Listener error:", e);
            }
        });
    }

    /**
     * 添加消息监听器（页面注册用）
     * @param {Function} callback - 接收消息的函数
     */
    addListener(callback) {
        if (typeof callback !== 'function') return;
        this.messageListeners.push(callback);

        // 返回卸载函数
        return () => {
            this.removeListener(callback);
        };
    }

    removeListener(callback) {
        const index = this.messageListeners.indexOf(callback);
        if (index > -1) {
            this.messageListeners.splice(index, 1);
        }
    }

    /**
     * 发送消息到后端（如果需要双向通信）
     */
    send(data) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(typeof data === 'object' ? JSON.stringify(data) : data + '');
        } else {
            console.warn("WebSocket not open. Cannot send:", data);
        }
    }

    /**
     * 安排自动重连（指数退避）
     */
    scheduleReconnect() {
        if (this.reconnectTimer) return;

        let delay = this.reconnectDelay;
        this.reconnectTimer = setTimeout(() => {
            this.reconnectTimer = null;
            this.reconnectDelay = Math.min(this.reconnectDelay * 1.5, this.maxReconnectDelay);
            this.connect();
        }, delay);
    }

    clearReconnectTimer() {
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        this.reconnectDelay = 3000; // 重置延迟
    }

    /**
     * 主动关闭连接（一般不需要手动调）
     */
    close() {
        this.clearReconnectTimer();
        if (this.ws) {
            this.ws.close();
            this.ws = null;
        }
        this.readyState = 'CLOSED';
    }
}

// 👇 导出全局唯一实例（单例模式）
if (typeof window !== 'undefined') {
    if (!window.WebSocketDevice) {
        window.WebSocketDevice = new DeviceWebSocket();
    }
    // 也可通过模块方式导出（现代浏览器支持）
    window.DeviceWebSocket = DeviceWebSocket; // 方便调试
}